// 等待页面加载完成
// 定义一个函数来检查元素是否存在
function checkForElement() {
    // 尝试查找具有指定类名的元素
    // 由于当这个元素渲染出来之前加载overall会导致页面崩溃，所以轮询检查它。
    var element = document.querySelector('.header-avatar-wrap');

    // 如果找到了该元素，输出到控制台并停止轮询
    if (element) {
        // console.log('Element found:', element);
        overall();
        clearInterval(intervalId); // 清除定时器停止轮询
    }
}

// 设置定时器每500毫秒检查一次
var intervalId = setInterval(checkForElement, 500);

// setTimeout(() => {

// 总函数：在页面渲染好之后就调用
function overall(){


    // const API_URL = "https://192.169.3.10:8505/api"
    const API_URL = "https://lyc.opchatai.site/api"

    $('.up-panel-container').append(
        "<div id='bilisummarizeArea'>" +
            "<img id='bilidownloadImg' src='https://forest-cloud.awsl.info/f/1yWid/biliSummarize.png' alt='总结视频'/>" +
            "<span id='bilisummarizeHeadup'>点击一键总结视频</span>" +
            "<div id='bilisummarizeContent'></div>" +
            "<div id='copy-tip' class='copyTip'></div>" +
            "<button id='bilicopyButton' class='bilicopyButton'>复制</button>" +
            "<button id='biliresetButton' class='biliresetButton'>重置</button>" +
        "</div>" +
        "<div id='bilichatArea'>" +
            "<div id='bilichatContent'></div>" +
            "<div class=\"messageBubble sentBubble\" id='bilichatQuestion'></div>" +
            "<div class=\"messageBubble receivedBubble\" id='bilichatAnswer'>你好，有什么需要回答的吗？</div>" +

            "<input id='bilichatInput' placeholder='有什么想问AI的？'>" +
            "<button id='bilichatSend' class='bilichatSend'>发送</button>" +
        "</div>"
    );

    // 创建样式元素
    const styleElement = document.createElement('style');

    // 设置样式内容
    styleElement.textContent = `
      #bilisummarizeArea{
        position: relative;
        border-radius: 7px;
        margin-bottom: 10px;
        background: #f1f2f3;
        cursor: pointer;
        display: block;
      }
      
      #bilichatArea{
        position: relative;
        margin-bottom: 10px;
        display: none;
        padding: 5px;
        box-shadow: 2px 2px 5px 0px rgba(0, 0, 0, 0.5);
        
        flex-direction: column;
      }

      #bilidownloadImg{
        width: 50px;
        height: 60px;
      }
      
      #bilisummarizeHeadup{
        word-wrap: break-word; 
      }
      
      #bilisummarizeContent{
        margin:5px;
      }
      
      .bilicopyButton{
        position:absolute;
        top:10px;
        right:60px;
        width: 40px;
        height:30px;
        border-radius: 10px;
        display:none;
        border: 1px solid gray;
        box-shadow: 0px 0px 3px 1px gray;
        cursor: pointer;
      }
      
      .biliresetButton{
        position:absolute;
        top:10px;
        right:10px;
        width: 40px;
        height:30px;
        border-radius: 10px;
        display:none;
        border: 1px solid gray;
        box-shadow: 0px 0px 3px 1px gray;
        cursor: pointer;
      }
      
      .copyTip{
        display:none;
        text-align:center;
        width:50%;
        position:absolute;
        top:50%;
        left:50%;
        transform:translate(-50%,-50%);
        background-color:black;
        color:white;
        padding:8px;
        border-radius:5px;
      }
      
      #bilichatInput{
        width:80%;
        display:none;
        border:none;
      }
      
      #bilichatSend{
        position:absolute;
        bottom:2px;
        right:5px;
        width: 60px;
        height:25px;
        border:none;
        border-radius: 10px;
        display:none;
        cursor: pointer;
        
        color: green;
      }
      
        .messageBubble {
            max-width: 80%;
            padding: 3px 10px;
            border-radius: 15px;
            margin-bottom: 10px;
        }

        .sentBubble {
            background-color: #DCF8C6;
            align-self: flex-end;
            display: none;
        }

        .receivedBubble {
            background-color: #F0F0F0;
            align-self: flex-start;
        }

    `;

    // 注入样式元素
    document.head.appendChild(styleElement);

    let hasAnalyzedSubtitle = false;
    $('#bilisummarizeArea').click(async function () {
        // testConnection();

        // 点击展开的函数
        if (!hasAnalyzedSubtitle) {
            const headup = document.getElementById("bilisummarizeHeadup");
            headup.innerText = "AI正在分析视频中...";
            headup.style.color = "orangered";

            analyzeSubtitle();
            hasAnalyzedSubtitle = true;

            $('#bilisummarizeArea').css('cursor', 'default');


        }
    });

    function testConnection(){
        var url = API_URL + "/testConnection";
        fetch(url)
            .then((response) => response.json())
            .then((data) => {
                console.log(data);
                if (data.success){
                    console.log("链接成功：");
                    console.log(data.message);
                } else {
                    console.log("链接异常。");
                    console.log(data.message);
                }
            });
    }

    function analyzeSubtitle(){
        var currentURL = window.location.href;
        getVideoInfoFromUrl(currentURL).then(result => {
            if (result.success){
                var aid = result.aid;
                var cid = result.cid;
                var title = result.title;
                // 去除 emoji 表情符号
                title = title.replace(/(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/g, '');

                // 去除其他特殊字符
                title = title.replace(/[^0-9a-zA-Z\u4e00-\u9fa5 ]/g, '');
                // console.log(aid);
                // console.log(cid);
                // console.log(title);
                getAISubtitleURL(aid,cid).then(result2 => {
                    if (result2.success){
                        // console.log(result2.subtitleUrl);
                        summarize(aid,cid,result2.subtitleUrl,title).then(summarizeResult=>{
                            var aiText;
                            aiText = summarizeResult.aiText;


                            const headup = document.getElementById("bilisummarizeHeadup");
                            headup.innerText = "本视频总结内容如下：";
                            headup.style.color = "green";

                            // await pretendTalking(aiText);
                            const content = document.getElementById("bilisummarizeContent");
                            content.innerHTML = aiText;
                                // + "<a class=\"jump-link video-time\" data-video-part=\"-1\" data-video-time=\"271\">4:31</a>"; //测试+时间戳，但是加出来的时间戳点不动

                            //显示复制按钮
                            $('#bilicopyButton').css('display', 'block');

                            //显示重置按钮
                            $('#biliresetButton').css('display', 'block');

                            //显示对话输入框、按钮
                            $('#bilichatArea').css('display', 'flex');
                            $('#bilichatInput').css('display', 'block');
                            $('#bilichatSend').css('display', 'block');

                            //更新提示信息（剩余次数）
                            updatePlaceHolder();

                        })
                        .catch(error3 => {
                            console.error(error3);
                            alert("获取视频总结失败！");

                        })
                    } else {
                        console.log(result2.message);
                        alert(result2.message);
                    }
                })
                    .catch(error2 => {
                        console.error(error2);
                        alert("获取视频字幕失败！");
                    })
            } else {
                console.log(result.message);
                alert("获取视频信息失败！");
            }
        })
        .catch(error => {
            // 在这里处理错误
            console.error(error);
            alert("获取视频信息失败！");
        })
    }

    /**
     * 在视频总结区域，即使是从数据库读取的现有结果，也不直接全部呈现，而是装作对话一样，一节一节地蹦出来。
     */
    function pretendTalking(aiText) {
        return new Promise((resolve) => {
            const content = document.getElementById("bilisummarizeContent");
            content.innerHTML = "";  // 清空内容
            let index = 0;

            const interval = setInterval(() => {
                if (index < aiText.length) {
                    if (aiText.slice(index, index + 4) === '<br>') {
                        content.innerHTML += '<br>';
                        index += 4;  // 跳过 <br> 标签
                    } else {
                        content.innerHTML += aiText[index];
                        index++;
                    }
                } else {
                    clearInterval(interval);
                    resolve();  // 文字显示完毕后解决Promise
                }
            }, 30);
        });
    }

    /**
     * 复制：复制文本区的全部内容到剪切板 并弹出成功提示1秒
     */
    $('#bilicopyButton').click(
    function copy(){
        // 创建一个临时的 textarea 元素
        var aiText = document.getElementById("bilisummarizeContent").innerText;
        const textarea = document.createElement("textarea");
        textarea.value = aiText.replaceAll("<br>","\n");

        // 将 textarea 添加到页面中
        document.body.appendChild(textarea);

        // 选择并复制文本
        textarea.select();
        document.execCommand("copy");

        // 移除临时元素
        document.body.removeChild(textarea);

        // 显示复制成功提示框
        var copyTip = document.getElementById('copy-tip');
        copyTip.innerHTML = '复制成功';
        copyTip.style.display = 'block';
        // 1秒后隐藏提示框
        setTimeout(function() {
            copyTip.style.display = 'none';
        }, 1000);
    });

    /**
     * 重置：重置文本框的提示与内容，重置区域样式，移除按钮
     */
    $('#biliresetButton').click(
        function buttonReset(){
            event.stopPropagation();
            reset();
        }
    );



    /**
     * 1. 通过 URL 解析得到视频的信息
     * 从 url 提取 BVID 与分 P，请求接口获取 aid、cid
     */
    function getVideoInfoFromUrl(url) {
        return new Promise((resolve, reject) => {
            // 从 URL 中提取 BVID。URL 有两种类型，一种是 / 结尾，一种是 ? 结尾。
            const start = url.indexOf("/BV");
            let end = url.indexOf("/", start + 1);
            const questionMarkIndex = url.indexOf("?");
            if (end === -1 || (questionMarkIndex !== -1 && questionMarkIndex < end)) {
                end = questionMarkIndex !== -1 ? questionMarkIndex : url.length;
            }
            const bvid = url.substring(start + 1, end);

            const pattern = /p=(\d+)/; // 匹配 p=x 的正则表达式

            // 从 URL 中提取 p
            const match = url.match(pattern);
            const p = match ? parseInt(match[1]) : 1

            const videoInfo = {
                aid: null,
                cid: null,
                message: "",
                success: false,
                title: "",
            };

            const apiUrl = `https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`;

            fetch(apiUrl)
                .then((response) => response.json())
                .then((data) => {
                    if (data.code === 0) {
                        // 获取 aid
                        const aid = data.data.aid;

                        // 获取 cid
                        const page = data.data.pages[p - 1];
                        const cid = page.cid;

                        // 获取 title: 如果 P=1 则直接取大标题，如果 P!=1，取大标题+小标题
                        const title = p === 1 ? data.data.title : `${data.data.title} ${page.part}`;

                        // 封装到结果中
                        videoInfo.aid = aid;
                        videoInfo.cid = cid;
                        videoInfo.title = title;
                        videoInfo.success = true;
                        videoInfo.message = "获取成功";

                        resolve(videoInfo);
                    } else {
                        videoInfo.message = "获取视频信息失败！";
                        reject(videoInfo);
                    }
                })
                .catch((error) => {
                    videoInfo.message = `获取视频信息失败！参考信息：${error.message}`;
                    reject(videoInfo);
                });
        });
    }

    /**
     * 通过 aid、cid 和 sessdata 获取字幕接口的 URL 地址
     * 这个地址顺便也会解析出用户的信息
     */
    async function getAISubtitleURL(aid, cid) {
        const result = {
            success: false,
            message: '',
            nickname: '',
            mid: '',
            subtitleUrl: '',
        };

        try {
            const url = `https://api.bilibili.com/x/player/v2?aid=${aid}&cid=${cid}`;
            const response = await fetch(url, {
                credentials: 'include'
            });

            if (response.ok) {
                const jsonResponse = await response.json();
                const data = jsonResponse.data;

                // 获取用户的 ID 和昵称
                const mid = data.login_mid;
                const nickname = data.name;

                // 如果Mid为空，则直接返回失败，提醒用户登录
                // console.log(data);
                if (mid == null || mid === 0){
                    result.success = false;
                    result.message = "请在登录B站后进行解析";
                    const headup = document.getElementById("bilisummarizeHeadup");
                    headup.innerText = "请在登录B站后进行解析";
                    headup.style.color = "red";
                    $('#biliresetButton').css('display', 'block');
                    return result;
                } else {
                    //检查缓存，如果缓存中没有存mid或者存的不一样，则将缓存的mid换成本MID
                    saveBiliMid(mid);
                }

                const subtitle = data.subtitle;
                const subtitles = subtitle.subtitles;

                if (subtitles.length > 0) {
                    const target = subtitles[0];
                    const subtitleUrl = `https:${target.subtitle_url}`;

                    result.nickname = nickname;
                    result.mid = mid;
                    result.subtitleUrl = subtitleUrl;
                    result.message = '获取成功';
                    result.success = true;
                } else {
                    result.message = '该视频没有字幕';
                    const headup = document.getElementById("bilisummarizeHeadup");
                    headup.innerText = "该视频没有AI字幕，无法解析";
                    headup.style.color = "red";
                    $('#biliresetButton').css('display', 'block');
                }
            } else {
                result.message = `请求字幕信息失败，错误码：${response.status}`;
            }
        } catch (error) {
            if (error.message === 'JSONArray[0] not found.') {
                result.message = '该视频没有字幕';
            } else {
                result.message = `请求字幕信息失败，参考信息：${error.message}`;
                sendErrorReport('接口异常', result.message);
            }
        }

        return result;
    }

    /**
     * 3. 携带字幕url请求后端，进行AI视频总结
     *
     */
    async function summarize(aid, cid, subtitleUrl, title){
        const result2 = {
            success: false,
            message: '',
            aiText: '',
        };

        const formData = new FormData();
        formData.append('aid', aid);
        formData.append('cid', cid);
        formData.append('subtitleUrl', subtitleUrl);
        formData.append('title', title);

        // console.log(aid);
        // console.log(cid);
        // console.log(subtitleUrl);

        try {
            var url = API_URL + "/summarizeWithDetail";
            const response = await fetch(url, {
                method: 'POST',
                mode: 'cors',
                body: formData
            });
                const contentType = response.headers.get('Content-Type');

                if (contentType && contentType.includes('application/json')) {
                    const jsonResponse = await response.json();
                    const data = jsonResponse.data;
                    if (jsonResponse.success){
                        if (data.aiText != null){
                            result2.aiText = data.aiText;
                            result2.message = data.message;
                        } else {
                            result2.aiText = data.summarize;
                            result2.message = data.message;
                        }
                        result2.success = true;
                        result2.aiText = result2.aiText.replace(/\n/g, "<br>");
                        result2.aiText = result2.aiText.replace("\\n\\r", "<br>");
                        await pretendTalking(result2.aiText);
                    } else {
                        result2.message = data.message;
                        alert("请求AI总结失败");
                    }
                } else if (contentType && contentType.includes('text/event-stream')) {
                    // 如果本视频第一次被解析，那么返回的将是信息流
                    const reader = response.body.getReader();
                    const textDecoder = new TextDecoder();
                    const contentPattern = /"content":"([^"\\]+(?:\\.[^"\\]+)*)"/;
                    const aiTextRegex = /data:\{"success":true,"message":"GPT对话完成","data":\{"aiText":"(.*?)"\}\}/;
                    var aiAnswerFinal = "";

                    var aiAnswer = "";
                    const content = document.getElementById("bilisummarizeContent");
                    async function readStream() {

                        while (true) {
                            const { done, value } = await reader.read();
                            if (done) {
                                break;
                            }

                            var textChunk = textDecoder.decode(value, { stream: true });
                            // 尝试匹配消息发送完毕后最后的拼接内容
                            const matchFinal = textChunk.match(aiTextRegex);

                            if (matchFinal && matchFinal[1]) {
                                aiAnswerFinal = matchFinal[1].replace(/\\r\\n/g, '<br>'); // 将 \r\n 替换为 <br>
                            }

                            const lines = textChunk.split('\n');


                            for (const line of lines) {
                                const match = line.match(contentPattern);
                                if (match) {
                                    aiAnswer = aiAnswer + match[1];
                                    content.innerHTML = aiAnswer;
                                }
                            }
                        }
                        // aiAnswer = aiAnswer.replace(/\n/g, "<br>");
                        result2.aiText = aiAnswer;
                        result2.message = "AI总结完成。";
                        result2.success = true;

                        if (aiAnswerFinal && aiAnswerFinal.trim()) {
                            content.innerHTML = aiAnswerFinal;
                            result2.aiText = aiAnswerFinal;
                        }

                    }

                    await readStream();
                }

        } catch (error) {
            alert("请求AI总结失败");
            console.error(error);
        }

        return result2;
    }


    $('#bilichatSend').click(async function () {

        var userText = document.getElementById("bilichatInput").value;
        if (!userText || !userText.trim()){
            alert("提问内容不可为空");
            return;
        }


        // 点击发送对话的函数
        await chatSend();
    });

    /**
     * 向AI提问
     */
    async function chatSend(){
        const result2 = {
            success: false,
            message: '',
            aiText: '',
        };
        var userText = document.getElementById("bilichatInput").value;
        if (!userText || !userText.trim()){
            alert("提问内容不可为空");
            result2.message = "提问内容不可为空";
            return result2;
        }


        const headup = document.getElementById("bilisummarizeHeadup");
        headup.innerText = "AI正在思考你的问题...";
        headup.style.color = "orangered";
        document.getElementById("bilichatInput").value = "";
        document.getElementById("bilichatInput").placeholder = "AI正在思考你的问题...";

        const content = document.getElementById("bilichatContent");
        const dialogQuestion = document.getElementById("bilichatQuestion");
        const dialogAnswer = document.getElementById("bilichatAnswer");
        // var aiAnswer= "你的提问: "+userText +"<br> AI回答: ";
        // content.innerHTML = aiAnswer;

        var aiAnswer = "";
        dialogQuestion.style.display = "block";
        dialogQuestion.innerHTML = userText;
        dialogAnswer.innerHTML = "AI正在思考你的问题...";


        const chatButton = document.getElementById("bilichatSend");
        chatButton.disabled = true;

        var currentURL = window.location.href;
        getVideoInfoFromUrl(currentURL).then(async result => {
            if (result.success) {
                var aid = result.aid;
                var cid = result.cid;
                var mid = getBiliMid();


                const formData = new FormData();
                formData.append('aid', aid);
                formData.append('cid', cid);
                formData.append('userId', mid);
                formData.append('userText', userText);

                try {
                    var url = API_URL + "/chatWithDetail";
                    const response = await fetch(url, {
                        method: 'POST',
                        mode: 'cors',
                        body: formData
                    });
                    const contentType = response.headers.get('Content-Type');
                    if (contentType && contentType.includes('application/json')) {
                        //问答阶段出现json回复，可能因为用户今日次数不足或者异常。
                        const jsonResponse = await response.json();



                        const headup = document.getElementById("bilisummarizeHeadup");
                        if (jsonResponse.message === "用户今日剩余对话次数不足！"){
                            headup.innerText = "今天的提问次数用完啦";
                            headup.style.color = "firebrick";
                            const biliInput = document.getElementById("bilichatInput");
                            biliInput.value = "";
                            biliInput.placeholder = "今天的提问次数用完啦，明天再来吧";
                        } else {
                            headup.innerText = "对话功能出错";
                            headup.style.color = "firebrick";
                        }

                    } else if (contentType && contentType.includes('text/event-stream')) {
                        // 对话应该都返回的是信息流
                        const reader = response.body.getReader();
                        const textDecoder = new TextDecoder();
                        const contentPattern = /"content":"([^"\\]+(?:\\.[^"\\]+)*)"/;
                        const aiTextRegex = /data:\{"success":true,"message":"GPT对话完成","data":\{"aiText":"(.*?)"\}\}/;
                        var aiAnswerFinal = "";
                        async function readStream() {

                            while (true) {
                                const { done, value } = await reader.read();
                                if (done) {
                                    break;
                                }

                                var textChunk = textDecoder.decode(value, { stream: true });

                                // 尝试匹配消息发送完毕后最后的拼接内容
                                const matchFinal = textChunk.match(aiTextRegex);

                                if (matchFinal && matchFinal[1]) {
                                    aiAnswerFinal = matchFinal[1].replace(/\\r\\n/g, '<br>'); // 将 \r\n 替换为 <br>
                                }

                                const lines = textChunk.split('\n');


                                for (const line of lines) {
                                    const match = line.match(contentPattern);
                                    if (match) {
                                        aiAnswer = aiAnswer + match[1];
                                        // content.innerHTML = aiAnswer;
                                        dialogAnswer.innerHTML = aiAnswer;
                                    }
                                }
                            }
                            // aiAnswer = aiAnswer.replace(/\n/g, "<br>");
                            result2.aiText = aiAnswer;
                            result2.message = "AI回复完成。";
                            result2.success = true;

                            const headup = document.getElementById("bilisummarizeHeadup");
                            headup.innerText = "AI回答完毕";
                            headup.style.color = "green";
                            if (aiAnswerFinal && aiAnswerFinal.trim()) {
                                // content.innerHTML = "你的提问: "+userText +"<br> AI回答: "+aiAnswerFinal;
                                dialogAnswer.innerHTML = aiAnswerFinal;
                            }

                            const chatButton = document.getElementById("bilichatSend");
                            chatButton.disabled = false;

                            //更新提示信息（剩余次数）
                            updatePlaceHolder();
                        }

                        await readStream();
                    }

                } catch (error) {
                    alert("请求AI总结失败");
                    console.error(error);
                }

                return result2;


            } else {
                alert("获取视频信息失败");
                console.log(result.message);
            }
        });
    }

    // 存储biliMid字段到LocalStorage
    function saveBiliMid(biliMid) {
        localStorage.setItem('biliMid', biliMid);
    }

    // 从LocalStorage中读取biliMid字段
    function getBiliMid() {
        return localStorage.getItem('biliMid');
    }

    // 获取 input 元素
    const input = document.getElementById('bilichatInput');

    // 监听 回车
    input.addEventListener('keyup', function(event) {
        // 判断按下的是否是回车键
        if (event.keyCode === 13) {
            // 按下回车时触发对话
            chatSend();
        }
    });

    async function getUserScore(){
        var mid = getBiliMid();
        if (!mid || !mid.trim()){
            console.log("用户未登录");
            return 0;
        }
        try {
            var url = API_URL + "/getUserScore?userId="+mid;

            const response = await fetch(url, {
                method: 'GET'
            });

            const jsonResponse = await response.json();
            const data = jsonResponse.data;
            return data.remainingScore;
        } catch (error){
            console.error(error);
            return 0;
        }
    }

    async function updatePlaceHolder(){
        var remainingScore = await getUserScore();
        var placeholder = "有什么想问AI的吗？(今日剩余"+remainingScore+"/10次)";
        const biliInput = document.getElementById("bilichatInput");
        biliInput.placeholder = placeholder;
    }

    // 监听 URL 变化
    function reset() {
        //重置文本框提示与内容
        const headup = document.getElementById("bilisummarizeHeadup");
        headup.innerText = "点击一键总结视频";
        headup.style.color = "black";

        const content = document.getElementById("bilisummarizeContent");
        content.innerHTML = "";
        const content2 = document.getElementById("bilichatContent");
        content2.innerHTML = "";
        const dialogQuestion = document.getElementById("bilichatQuestion");
        const dialogAnswer = document.getElementById("bilichatAnswer");
        dialogQuestion.innerHTML = "";
        dialogAnswer.innerHTML = "你好，有什么需要回答的吗？";

        //隐藏按钮
        $('#bilicopyButton').css('display', 'none');
        $('#biliresetButton').css('display', 'none');
        $('#bilichatArea').css('display', 'none');
        $('#bilichatInput').css('display', 'none');
        $('#bilichatSend').css('display', 'none');
        $('#bilichatQuestion').css('display', 'none');

        //重置样式并恢复点击分析功能
        $('#bilisummarizeArea').css('cursor', 'pointer');
        hasAnalyzedSubtitle = false;
    }

    /**
     * 轮询检查：当页面url发生变化时，触发总结器的重置。
     */
    function detectUrlChange() {
        let currentUrl = window.location.href;

        // 使用setInterval定时器定期检查URL是否发生变化
        setInterval(() => {
            if (window.location.href !== currentUrl) {
                currentUrl = window.location.href;
                reset();
            }
        }, 1000);
    }

// 调用函数来开始监听URL变化
    detectUrlChange();

}
// }, 5000);


